﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Inovout.Descriptors;
using System.Linq;
using System.ComponentModel.DataAnnotations;

namespace Inovout.Web
{
    public class ModelDescriptorModelMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
        {
            List<Attribute> attributeList = new List<Attribute>(attributes);
            if (containerType != null)
            {
                TypeDescriptor modelTypeDescriptor = TypeDescriptor.Create(containerType);
                PropertyDescriptor propertyDescriptor = modelTypeDescriptor.GetProperty(propertyName);


                if (!attributeList.Any(a => a.GetType().Equals(typeof(DisplayAttribute))))
                {
                    attributeList.Add(new DisplayAttribute { Name = propertyDescriptor.Alias });
                }
                ControlPartAttribute controlPartAttribute;
                if (propertyDescriptor.TryGetAttribute<ControlPartAttribute>(out controlPartAttribute))
                {
                    if (!attributeList.Any(a => a.GetType().Equals(typeof(UIHintAttribute))))
                    {
                        attributeList.Add(new UIHintAttribute(controlPartAttribute.ControlType.ToString()));

                    }

                    if (!attributeList.Any(a => a.GetType().Equals(typeof(RequiredAttribute))))
                    {
                        //错误信息可重新设置。
                        attributeList.Add(new RequiredAttribute { AllowEmptyStrings = !controlPartAttribute.IsRequired });
                    }
                    if (controlPartAttribute.MaxValue != null
                        && !attributeList.Any(a => a.GetType().Equals(typeof(StringLengthAttribute)))
                        && propertyDescriptor.PropertyType.Equals(typeof(string)))
                    {
                        attributeList.Add(new StringLengthAttribute(int.Parse(controlPartAttribute.MaxValue.ToString()))
                        {
                            MinimumLength = controlPartAttribute.MinValue == null ? 0 : int.Parse(controlPartAttribute.MinValue.ToString())
                        });
                    }
                }
            }
            return base.CreateMetadata(attributeList.ToArray(), containerType, modelAccessor, modelType, propertyName);
        }
    }
}
